package com.ynb.lighterbuffer;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
public class SerializerUtil {
	
	public static <T> void serialize(T o,BinaryWriter writer) throws Exception {
		if (o == null) {
			writer.writeBool(false);
			return;
		}
		@SuppressWarnings("unchecked")
		ISchema<T> schema = SchemaPool.getSchema((Class<T>) o.getClass());
		schema.serialize(o, writer);
	}
	
	public static <T> byte[] serialize(T o) throws Exception {
		BinaryWriter writer = BinaryIOBuilderFactory.buildWriter();
		serialize(o,writer);
		return writer.toArray();
	}

	public static <T> T deSerialize(Class<T> type, BinaryReader reader) throws Exception {
		ISchema<T> schema = SchemaPool.getSchema(type);
		return schema.deSerialize(type, reader);
	}
	
	public static <T> T deSerialize(Class<T> type, byte[] data) throws Exception {
		BinaryReader reader = BinaryIOBuilderFactory.buildReader(data);
		return deSerialize(type,reader);
	}

	public static <T> void serializeList(List<T> list, Class<T> genericityType,BinaryWriter writer) throws Exception {
		if (list == null) {
			writer.writeNull(true);
			return;
		}
		writer.writeNull(false);
		ISchema<T> schema = SchemaPool.getSchema(genericityType);
		writer.writeInt(list.size());
		for (T o : list) {
			schema.serialize(o, writer);
		}
	}
	
	public static <T> byte[] serializeList(List<T> list, Class<T> genericityType) throws Exception {
		BinaryWriter writer = BinaryIOBuilderFactory.buildWriter();
		serializeList(list,genericityType,writer);
		return writer.toArray();
	}

	public static <T> void deSerializeList(List<T> list, Class<T> genericityType, BinaryReader reader) throws Exception {
		if (reader.readNull()) {
			return;
		}
		ISchema<T> schema = SchemaPool.getSchema(genericityType);
		int size = reader.readInt();
		for (int i = 0; i < size; i++) {
			list.add(schema.deSerialize(genericityType, reader));
		}
	}
	
	public static <T> void deSerializeList(List<T> list, Class<T> genericityType, byte[] data) throws Exception {
		BinaryReader reader = BinaryIOBuilderFactory.buildReader(data);
		deSerializeList(list, genericityType, reader);
	}
	
	public static <TK, TV> void serializeMap(Map<TK, TV> map, Class<TK> genericityKeyType,
			Class<TV> genericityValueType,BinaryWriter writer) throws Exception {
		if (map == null) {
			writer.writeNull(true);
			return;
		}
		writer.writeNull(false);
		ISchema<TK> kschema = SchemaPool.getSchema(genericityKeyType);
		ISchema<TV> vschema = SchemaPool.getSchema(genericityValueType);
		writer.writeInt(map.size());
		for (Entry<TK, TV> en : map.entrySet()) {
			kschema.serialize(en.getKey(), writer);
			vschema.serialize(en.getValue(), writer);
		}
	}

	public static <TK, TV> byte[] serializeMap(Map<TK, TV> map, Class<TK> genericityKeyType,
			Class<TV> genericityValueType) throws Exception {
		BinaryWriter writer = BinaryIOBuilderFactory.buildWriter();
		serializeMap(map, genericityKeyType, genericityValueType,writer);
		return writer.toArray();
	}

	public static <TK, TV> void deSerializeMap(Map<TK, TV> map, Class<TK> genericityKeyType,
			Class<TV> genericityValueType,BinaryReader reader) throws Exception {
		if (reader.readNull()) {
			return;
		}
		ISchema<TK> kschema = SchemaPool.getSchema(genericityKeyType);
		ISchema<TV> vschema = SchemaPool.getSchema(genericityValueType);
		int size = reader.readInt();
		for (int i = 0; i < size; i++) {
			map.put(kschema.deSerialize(genericityKeyType, reader), vschema.deSerialize(genericityValueType, reader));
		}
	}
	
	public static <TK, TV> void deSerializeMap(Map<TK, TV> map, Class<TK> genericityKeyType,
			Class<TV> genericityValueType, byte[] data) throws Exception {
		BinaryReader reader = BinaryIOBuilderFactory.buildReader(data);
		deSerializeMap(map, genericityKeyType, genericityValueType, reader);
	}

}